
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt

import numpy as np
import random
from view.endSrc.MixedGaussianDatasetGenerator import MixedGaussianDatasetGenerator
from view.endSrc.MixedGaussianDataset import MixedGaussianDataset
from view.endSrc.NonoverlappingClustersDataGenerator import NonoverlappingClustersDataGenerator
from view.endSrc.DBConfig import DBConfig
from view.endSrc.MySqlConn import MySqlConn


def visualization(meanList, dataset, labels):

    '''
    This method conduct the dimensionality reduction process by principle component analysis,
    which transform the data to 2D data, and plot the 2D data and centers by clusters.

    Examples:
    --------
    dataset.visualization()
    '''

    k = len(meanList)
    dataACen = np.concatenate((meanList, dataset), axis=0)
    pca = PCA(n_components=2)
    pca.fit(dataACen)
    dataACen2d = pca.fit_transform(dataACen)
    Center2d = dataACen2d[:k ,:]
    data2d = dataACen2d[k: ,:]
    x = data2d[: ,0]
    y = data2d[: ,1]
    plt.scatter(x ,y ,c=labels ,marker="+")
    for i in range(k):
        plt.plot(Center2d[i ,0], Center2d[i ,1], c = 'r', marker = 'x')
        text = "c" + str( i +1)
        plt.annotate(text, xy = (Center2d[i ,0], Center2d[i ,1]),
                     xytext = (Center2d[i ,0 ] +1.5, Center2d[i ,1 ] +1.5))

    plt.xlabel('dimension 1')
    plt.ylabel('dimension 2')
    plt.title('Principle Component Analysis to 2D data')
    plt.show()


def visual2D(meanList, dataset, labels):

    k = len(meanList)
    plt.scatter(dataset[: ,0], dataset[: ,1],
                label='2D origin', c=labels, marker="+")
    for i in range(k):

        plt.plot(meanList[i][0], meanList[i][1], c ='r', marker ='x')
        text = "c" + str( i +1)
        plt.annotate(text, xy = (meanList[i][0], meanList[i][1]),
                     xytext = (meanList[i][0], meanList[i][1]))


    plt.xlabel('x')
    plt.ylabel('y')
    plt.title('2D origin data')
    plt.legend()
    plt.show()


def saveToDB():
    clusterNum = 6
    isEqu = False
    numOfInstances = 40000
    numOfFeatures = 2
    centerRange = [10, 1000]
    isOverlap = False
    overlap = 10
    # ######################################################################
    ps = []
    for i in range(clusterNum):
        if isEqu:
            ps.append(1)
        else:
            ps.append(random.uniform(1, 3))
    print(ps)
    ps = [20, 1, 1, 1, 1, 1]

    if isOverlap:
        g = MixedGaussianDatasetGenerator(numOfInstances=numOfInstances, numOfFeatures=numOfFeatures,
                                          overlap=overlap,
                                          paiList=ps,
                                          xRange=centerRange)
    else:
        g = NonoverlappingClustersDataGenerator(numOfInstances=numOfInstances, numOfFeatures=numOfFeatures, paiList=ps, centerRange=centerRange)

    g.genSeparableComponents()
    dataset = g.genMixedDataset()

    # visualization(dataset.getTrueCentres(), dataset, dataset.getLabels())
    visual2D(dataset.getTrueCentres(), dataset, dataset.getLabels())

    yes = input('Want to save to DB?: ')
    if yes == 'y':
        sqlConn = MySqlConn(DBConfig())
        dataset.saveToDB(sqlConn, 'mixGaus')


def loadFromDB():
    sqlConn = MySqlConn(DBConfig())
    dataset = MixedGaussianDataset.fromDB(sqlConn, 2)

    print(dataset)

    visualization(dataset.getTrueCentres(), dataset, dataset.getLabels())
    visual2D(dataset.getTrueCentres(), dataset, dataset.getLabels())


saveToDB()
# loadFromDB()